from datetime import timedelta
from typing import BinaryIO, List

from minio import S3Error
from minio.commonconfig import CopySource

from config.config_minio import minio_client


def put_object(bucket_name, object_name, data: BinaryIO, length, part_size):
    """
    上传文件到 minio
    @param bucket_name: 存储桶
    @param object_name: 文件名
    @param data: 文件内容
    @param length: 文件大小
    @param part_size: 缓冲区大小
    @return:
    """
    make_bucket(bucket_name)
    return minio_client.put_object(
        bucket_name=bucket_name,
        object_name=object_name,
        data=data,
        length=length,
        part_size=part_size  # default -1 缓冲区自动分配
    )


def stat_object(bucket_name: str, object_name: str):
    """
    查看 minio 中的文件元信息
    @param bucket_name: 存储桶
    @param object_name: 文件名
    @return:
    """
    object_stat = minio_client.stat_object(bucket_name=bucket_name, object_name=object_name)
    stat = {
        "update_time": object_stat._last_modified,
        "size": object_stat._size
    }
    return stat


def get_presigned_url(bucket_name: str, object_name: str, method: str = "GET"):
    """
    获取对象签名路径，url 有限时间为 2 小时
    @param bucket_name: 存储桶
    @param object_name: 文件名
    @param method:  http 请求方法
    @return:
    """
    presigned_url: str = minio_client.get_presigned_url(
        bucket_name=bucket_name,
        object_name=object_name,
        method=method,
        # expires=timedelta(hours=2),  # 失效时间
    )
    # print(presigned_url)
    return presigned_url


def list_objects(bucket_name: str, recursive: bool = True):
    """
    获取存储桶中存储的文件名列表
    @param bucket_name: 存储桶
    @param recursive: 是否递归遍历
    @return:
    """
    objects: List = minio_client.list_objects(bucket_name, recursive=recursive)
    file_list = [obj.object_name for obj in objects]
    return file_list

def remove_obj(bucket_name: str, uuid: str):
    """
    删除 minio 中的文件
    @param bucket_name: 存储桶
    @param uuid: uuid替换原文件名
    @return:
    """
    minio_client.remove_object(bucket_name=bucket_name, object_name=uuid)


""" 确保 bucket 存在 """


def make_bucket(bucket_name):
    """
    检查存储桶是否存在，不存在这创建存储桶
    @param bucket_name: 存储桶
    @return:
    """
    if not minio_client.bucket_exists(bucket_name):
        minio_client.make_bucket(bucket_name)


# """ 修改文件名 """
#
#
# def update_obj_name(bucket_name, old_name, new_name):
#     """
#     修改文件名：只需要提供新的文件名，在 minio 服务中直接进行改名
#     @param bucket_name: 存储桶
#     @param old_name: 旧文件名
#     @param new_name: 新文件名
#     @return:
#     """
#     try:
#         copy_source = CopySource(bucket_name, old_name)
#         minio_client.copy_object(
#             bucket_name,
#             new_name,
#             copy_source,
#         )
#         print(f"Object '{old_name}' has been copied to '{new_name}'.")
#         remove_obj(bucket_name, old_name)
#         print(f"Old object '{old_name}' has been deleted.")
#     except S3Error as exc:
#         print(f"Error occurred: {exc}")
